package alkaid.eis.sys.controller;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import alkaid.eis.sys.entity.Dept;
import alkaid.eis.sys.entity.DeptComparator;
import alkaid.eis.sys.repository.DeptRepository;
import alkaid.eis.sys.service.DeptService;
import lombok.RequiredArgsConstructor;

/**
 * 部门接口
 * 
 * @author Lucky Yang
 * @since 0.0.1
 */
@RestController
@RequestMapping("/depts")
@RequiredArgsConstructor
public class DeptController {
    private final DeptRepository deptRepository;
    private final DeptService deptService;

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public Long create(@RequestParam(name = "parentId", required = false) Long parentId,
            @RequestBody DeptDto deptDto) {
        Dept entity = deptService.save(parentId, DeptMapper.INST.toEntity(deptDto));
        return entity.getId();
    }

    @PutMapping("/{id}")
    public Long update(@PathVariable("id") Long id, @RequestBody DeptDto deptDto) {
        Dept entity = deptService.update(id, DeptMapper.INST.toEntity(deptDto));
        return entity.getId();
    }

    @DeleteMapping("/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void delete(@PathVariable("id") Long id) {
        deptService.delete(id);
    }

    @GetMapping("/all")
    public List<DeptFlatDto> getAll() {
        return deptRepository.findAll().stream()
                .sorted(DeptComparator.PATHID)
                .map(DeptFlatDto::of)
                .collect(Collectors.toList());
    }

    @GetMapping("/all-full-name")
    public Map<Long, String> getAllFullName() {
        return deptService.findFullName();
    }

    @GetMapping("/top")
    public List<DeptDto> getTop() {
        List<Dept> entities = deptRepository.findByParentIsNull();
        Collections.sort(entities, DeptComparator.ORDERNO_NAME);
        return DeptMapper.INST.toDto(entities);
    }

    @GetMapping("/{id}/children")
    public List<DeptDto> getChildren(@PathVariable("id") Long id) {
        Dept parent = deptService.findById(id);
        List<Dept> entities = deptRepository.findChildByParent(parent);
        Collections.sort(entities, DeptComparator.ORDERNO_NAME);
        return DeptMapper.INST.toDto(entities);
    }

    @GetMapping("/{id}")
    public DeptDto getById(@PathVariable("id") Long id) {
        Dept entity = deptService.findById(id);
        return DeptMapper.INST.toDto(entity);
    }
}
